package utils;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

public class Scanner {

    /**
     * 从包package中获取所有的Class
     *
     * @param packageName
     * @return
     */
    public <A extends Annotation> Set<Class<?>> getClassSet(String packageName, Class<A> annotationClass) {
        Set<Class<?>> set=new HashSet<>();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
            String resourcePattern = "/**/*.class";
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+
                    ClassUtils.convertClassNameToResourcePath(packageName)+ resourcePattern;
            Resource[] resources =resourcePatternResolver.getResources(pattern);
            MetadataReaderFactory readerfactory =new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource: resources) {
                MetadataReader reader = readerfactory.getMetadataReader(resource);
                //扫描到的class
                String classname = reader.getClassMetadata().getClassName();
                Class<?> clazz = Class.forName(classname);
                //判断是否有指定主解
                A anno = clazz.getAnnotation(annotationClass);
                if(anno != null) {
                    set.add(clazz);
                }
            }
        }catch(IOException | ClassNotFoundException e) {
            System.out.println(ExceptionUtils.toString(e));
        }
        return set;
    }

}
